package com.boho.ecp.base.service;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.Cookie;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import cn.boho.framework.context.ActionContext;

import com.boho.ecp.base.model.UserCookie;
import com.boho.ecp.util.JsonUtils;

/**
 * 
 * @author 陈伟
 * @memo Deprecated为未修改完成，非本人请勿使用
 */
public class CookieService {
	
	private final static Logger log = Logger.getLogger(CookieService.class);
	
	private final static String PARAM_COOKIE = "PARAM_COOKIE";
	private final static String TMP_COOKIE = "TMP_COOKIE";
	
	public final static String securityCode = "422633cf-3c90-4164-b6d8-05dfdae35dfe";
	
	private static void addCookie(ActionContext atx, String domain, String path,
    		String cookieName, String cookieValue, int age) {
    	
        Cookie cookie = new Cookie(cookieName, encrypt(cookieValue));
        cookie.setMaxAge(age);
        
        if (StringUtils.isNotBlank(domain)) {
        	cookie.setDomain(domain);
        }
        
        if (StringUtils.isNotBlank(path)) {
        	cookie.setPath(path);
        }
        
        atx.getHttpResponse().addCookie(cookie);
    }
	
	public static Map<String, String> getCookies(ActionContext atx){
		Map<String,String> cookieMap = new HashMap<String,String>();
		
		Cookie[] cookies = atx.getHttpRequest().getCookies();
        if (cookies != null) {
	        for (int i = 0; i < cookies.length; i++) {
	            Cookie cookie = cookies[i];
	            String cookieName = cookie.getName();
	            
	            cookieMap.put(cookieName, decrypt(cookie.getValue()));
	        }
        }
        
        return cookieMap;
	}
	
	@Deprecated
	public static Map<String,String> getCookies(ActionContext atx, Set<String> parseCookie) {
		Map<String,String> cookieMap = new HashMap<String,String>();
		if(parseCookie.isEmpty()){
			parseCookie.add(PARAM_COOKIE);
			parseCookie.add(TMP_COOKIE);
		}
		
		Cookie[] cookies = atx.getHttpRequest().getCookies();
        if (cookies != null) {
	        for (int i = 0; i < cookies.length; i++) {
	            Cookie cookie = cookies[i];
	            String cookieName = cookie.getName();
	            if(!parseCookie.contains(cookieName)){
	            	continue;
	            }
	            
	            cookieMap.put(cookieName, decrypt(cookie.getValue()));
	        }
        }
        return cookieMap;
	}
	
	public static String getValue(ActionContext atx, String key) {
		return getValue(atx, key, "");
	}
	
	public static String getValue(ActionContext atx, String key, String defaultValue) {
		Map<String,String> map = getCookies(atx);
		if(map.isEmpty()){
			return defaultValue;
		}
		return map.get(key);
	}
	
	/**
     * 保存Cookie
     */
    public static void saveCookie(ActionContext atx, String domain, String path, String cookieName, int age) {
    	Set<String> set = new HashSet<String>();
    	set.add(cookieName);
    	
        addCookie(atx, domain, path, cookieName, joinItem(getCookies(atx,set)), age);
    }
    
    public static void saveCookie(ActionContext atx, String domain, String path, String cookieName, String value, int age) {
        addCookie(atx, domain, path, cookieName, value, age);
    }
    
    /**
     * 删除Cookie
     */
    public static void removeCookie(ActionContext atx, String domain, String path, String cookieName) {
    	
    	saveCookie(atx, domain, path, cookieName, 0);
    }
    
    @Deprecated
    private static String joinItem(Map itemMap){
    	return "";
    }
    
    /**
	 * 加密
	 */
	public static String encrypt(String str) {
		if (str == null) {
			return null;
		}
		
		if (StringUtils.isBlank(securityCode)) {
			return str;
		}
		
		byte[] bytes;
		try {
			bytes = str.getBytes("UTF-8");
		} catch (Exception ex) {
			log.error("failed to encrypt cookie value: " + str, ex);
			return null;
		}
		
		int mask = securityCode.hashCode();
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < bytes.length; i++) {
			int v = mask ^ bytes[i];
			sb.append(getChar(v));
			sb.append(getChar(v >>> 4));
		}
		
		return sb.toString();
	}
	
	/**
	 * 解密
	 */
	public static String decrypt(String str) {
		if (str == null) {
			return null;
		}
		
		if (StringUtils.isBlank(securityCode)) {
			return str;
		}
		
		char[] ca = str.toCharArray();
		byte[] bytes = new byte[ca.length / 2];
		     
		int mask = securityCode.hashCode();
		for (int i = 0; i < bytes.length; i++) {
			int v = getInt(ca[i * 2]);
			v |= getInt(ca[i * 2 + 1]) << 4;
			bytes[i] = (byte) (v ^ mask);
		}
		
		try {
			return new String(bytes, "UTF-8");
		} catch (Exception ex) {
			log.error("failed to decrypt cookie value: " + str, ex);
			return null;
		}
	}
	
	private static char getChar(int val) {
        int part = 0x0F & val;
        if (part < 10) {
        	return (char) ('0' + part);
        } else {
        	return (char) ('a' + part - 10);
        }
    }
	
	private static int getInt(char c) {
		if (c <= '9') {
			return c - '0';
		} else {
			return c - 'a' + 10;
		}
	}
	
	public static void main(String[] args) throws Exception{
		String s = "{\"uid\":2,\"product\":[{\"id\":50001513,\"qty\":1},{\"id\":50001804,\"qty\":4},{\"id\":50001874,\"qty\":1},{\"id\":50001606,\"qty\":1}],\"items\":4}";
		s = encrypt(s);
		System.out.println(s);
//		securityCode = "asdasds";
		s = decrypt(s);
		System.out.println(s);
		UserCookie userCookie = JsonUtils.fromJson(s, UserCookie.class);
	}

	
}
